package Helpers
{
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class ProximityWatcher
	{
		protected var handler:Function;
		protected var stage:Stage;
		protected var area:Rectangle;
		
		protected var lastWasInside:Boolean;
		
		public function ProximityWatcher(stage:Stage, area:Rectangle, handler:Function)
		{
			this.stage = stage;
			this.area = area;
			this.handler = handler;
			lastWasInside = isInside();
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
		}
		
		public static function watch(target:DisplayObject, border:int, handler:Function):ProximityWatcher
		{
			var rect:Rectangle = new Rectangle();
			var point:Point = target.localToGlobal(new Point(0,0));
			point = target.stage.globalToLocal(point);
			rect.x = point.x - border;
			rect.y = point.y - border;
			rect.width = target.width + border * 2;
			rect.height = target.height + border * 2;
			return new ProximityWatcher(target.stage, rect, handler);
		}
		
		public function unWatch():void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
		}
		
		protected function mouseMoveHandler(evt:MouseEvent):void
		{
			var currentIsInside:Boolean = isInside();
			if(currentIsInside != lastWasInside)
			{
				lastWasInside = currentIsInside;
				var type:String = currentIsInside ?
									ProximityEvent.PROXIMITY_ENTER :
									ProximityEvent.PROXIMITY_EXIT;
				var proxEvt:ProximityEvent = new ProximityEvent(type);
				handler(proxEvt);
			}
		}
		
		protected function isInside():Boolean
		{
			var mouseX:int = stage.mouseX;
			var mouseY:int = stage.mouseY;
			if(mouseX < area.x || mouseX > area.x + area.width)
				return false;
			if(mouseY < area.y || mouseY > area.y + area.height)
				return false;
			return true;
		}
	}
}